using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using Microsoft.VisualStudio.DebuggerVisualizers;

namespace TankerVisualizer
{
    public partial class SequenceVisualizerForm : Form, IDisposable
    {              
        public SequenceVisualizerForm(IVisualizerObjectProvider objectProvider)
        {
            InitializeComponent();
            FillTreeView(objectProvider);                                       
        }

        private void FillTreeView(IVisualizerObjectProvider objectProvider)
        {
            BinaryFormatter formatter = new BinaryFormatter();
            IEnumerable data = null;
            using (Stream stream = objectProvider.GetData())
            {
                data = formatter.Deserialize(stream) as IEnumerable;                
            }

            if (data != null)
            {
                Cursor.Current = Cursors.WaitCursor;
                sequenceItemTreeView.BeginUpdate();
                sequenceItemTreeView.Nodes.Clear();
                TreeNode rootNode = new TreeNode("Values");
                foreach (object item in data)
                {
                    TreeNode node = new TreeNode(item.ToString());
                    if (!(item is ValueType))
                    {
                        node.Tag = item;
                    }
                    rootNode.Nodes.Add(node);
                }
                sequenceItemTreeView.Nodes.Add(rootNode);
                sequenceItemTreeView.EndUpdate();
                sequenceItemTreeView.ExpandAll();
                Cursor.Current = Cursors.Default;
            }
        }

        private IEnumerable<TreeNode> GetAllTreeNode()
        {
            foreach (TreeNode node in sequenceItemTreeView.Nodes)
            {
                yield return node;
                foreach (TreeNode childNode in GetChildTreeNode(node))
                {
                    yield return childNode;
                }
            }
        }

        private IEnumerable<TreeNode> GetChildTreeNode(TreeNode treeNode)
        {
            if (treeNode.Nodes.Count > 0)
            {
                foreach (TreeNode node in treeNode.Nodes)
                {
                    yield return node;
                    GetChildTreeNode(node);
                }
            }
        }

        private void SequenceItemTreeViewAfterSelect(object sender, TreeViewEventArgs e)
        {
            itemPropertyGrid.SelectedObject = e.Node.Tag;
        }

        #region IDisposable Members

        void IDisposable.Dispose()
        {            
            foreach (TreeNode node in GetAllTreeNode())
            {
                node.Tag = null;
            }           
        }

        #endregion
    }
}